/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package cifar10;

import cifar10.featureextraction.AutoColorCorrelogramWrapper;
import cifar10.featureextraction.AvgColorFeatureExtractor;
import cifar10.featureextraction.Combiner;
import cifar10.featureextraction.FixedSizeFeatureExtractor;
import cifar10.featureextraction.HistogramWrapper;
import cifar10.util.Alphabet;
import cifar10.util.NamedImage;
import cifar10.util.NamedImages;
import com.google.common.collect.Lists;
import de.lmu.ifi.dbs.jfeaturelib.features.AutoColorCorrelogram;
import de.lmu.ifi.dbs.jfeaturelib.features.CEDD;
import de.lmu.ifi.dbs.jfeaturelib.features.FeatureDescriptor;
import de.lmu.ifi.dbs.jfeaturelib.features.Haralick;
import ij.process.ColorProcessor;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * @author mwh
 */
public class JFeatureLibExtraction {

    static Character separator = ',';

    static String baseDir = "/home/mwh/kaggle/cifar10/";

    static Map<String, String> getLabels() throws IOException {
        BufferedReader reader = new BufferedReader(new FileReader(baseDir + "trainLabels.csv"));
        Map<String, String> labels = new HashMap<String, String>();
        String line;
        while ((line = reader.readLine()) != null) {
            String[] fields = line.split(",");
            labels.put(fields[0] + ".png", fields[1]);
        }
        return labels;
    }

    static public void main(String[] args) throws FileNotFoundException, IOException {
        Map<String, String> labels = null;
        labels = getLabels();

//        FixedSizeFeatureExtractor fe = new AutoColorCorrelogramWrapper();
//        FixedSizeFeatureExtractor fe = new AvgColorFeatureExtractor();
        List<FixedSizeFeatureExtractor> fes = new ArrayList<FixedSizeFeatureExtractor>();
        fes.add(new AvgColorFeatureExtractor());
        fes.add(new HistogramWrapper(10, HistogramWrapper.Type.RED));
        fes.add(new HistogramWrapper(10, HistogramWrapper.Type.GREEN));
        fes.add(new HistogramWrapper(10, HistogramWrapper.Type.BLUE));
        fes.add(new AutoColorCorrelogramWrapper());
        
        FixedSizeFeatureExtractor fe = new Combiner(fes);
        
        String filePrefix = "train-";

        PrintWriter csvWriter = new PrintWriter(baseDir + "featurefiles/" + filePrefix + "j-" + fe.getName() + ".csv");
        PrintWriter svmWriter = new PrintWriter(baseDir + "featurefiles/" + filePrefix + "j-" + fe.getName() + ".svm");

        Alphabet targetAlphabet = new Alphabet();
        targetAlphabet.load("targets.alp");

        StringBuilder headerLine = new StringBuilder();
        headerLine.append("ImgNo").append(separator).append("label").append(separator);
        addToStringBuilder(headerLine, fe.getFeatureNames());
        printStringBuilder(csvWriter, headerLine);

        NamedImages images = new NamedImages(baseDir + "train");

        int c = 1;
        for (NamedImage nm : images) {

            BufferedImage img = nm.getImage();

            System.err.println(c + "\t" + nm.getName());

            double[] featureValues = fe.getValues(img);

            StringBuilder line = new StringBuilder();
            String label = "null";
            if (labels != null) {
                label = labels.get(nm.getName());
            }
            line.append(nm.getName()).append(separator).append(label).append(separator);
            addToStringBuilder(line, featureValues);
            printStringBuilder(csvWriter, line);

            writeSparse(svmWriter, targetAlphabet.lookup(label), featureValues);
            c++;
        }

        svmWriter.close();
        csvWriter.close();

//        targetAlphabet.save("targets.alp");
    }

    public static void printStringBuilder(PrintWriter writer, StringBuilder sb) {
        Character lastChar = sb.charAt(sb.length() - 1);
        if (lastChar.equals(separator)) {
            sb.deleteCharAt(sb.length() - 1);
        }
        writer.println(sb.toString());
    }

    public static void addToStringBuilder(StringBuilder sb, List<String> elements) {
        for (String e : elements) {
            sb.append(e).append(separator);
        }
    }

    public static void addToStringBuilder(StringBuilder sb, String[] elements) {
        addToStringBuilder(sb, Arrays.asList(elements));
    }

    public static void addToStringBuilder(StringBuilder sb, double[] elements) {
        for (double e : elements) {
            sb.append(e).append(separator);
        }
    }

    public static void writeSparse(PrintWriter writer, int label, double[] elements) {

        StringBuilder sb = new StringBuilder();
        sb.append(label);
        for (int i = 0; i < elements.length; i++) {
            int fn = i + 1;
            if (elements[i] != 0) {
                sb.append(" ").append(fn).append(":").append(elements[i]);
            }

        }
        writer.println(sb.toString());

    }
}
